# -*- coding: utf-8 -*-
"""
@Time: 2021/12/1 20:00
@Author: 鹄望潇湘
@File: main.py
@desc:
python -m gobigger.bin.play --bot-only --player-num 3 --team-num 4 --agent-class my_submission.my_submission:MySubmission

global_state{
    border: [1000, 1000]
    total_time: 1000
    last_time: 0
    leaderboard: {'0': 9.0, '1': 9.0}
}
{
    '0':{
        feature_layer: list()，在该玩家视野里所有人的分身所在的区域
        rectangle: (73, 0, 373, 300)
        overlap:{
            food: list(x, y, r)
            thorns: list(x, y, r)
            spore: list(x, y, r)
            clone: list(x, y, r, player, team)
        }
        team_name: '0'
    }
    ...
}

"""

import random
import time

import pygame
from pygame.math import Vector2

from my_submission.my_submission import MySubmission

from gobigger.agents import BotAgent
from gobigger.server import Server
from gobigger.render import EnvRender, RealtimeRender

server = Server(dict(
    save_video=False,
    save_quality='high', # 保存的录像质量。默认为high，可以是low
    save_path='', # 保存录像路径。默认为空
    state_tick_per_second=40,
    action_tick_per_second=5,
    match_time=1000,
    team_num=3,  # 只有一支队伍
    player_num_per_team=1,  # 每支队伍有五个玩家
    obs_settings=dict(
        with_spatial=True,
        with_speed=False,
        with_all_vision=False,
    ),
))
render = RealtimeRender(server.map_width, server.map_height)
server.set_render(render)
server.reset() # 初始化游戏引擎
server.start()

human_team_name = '0' # 真人玩家控制的队伍名称
human_team_player_name = []

bot_agents = [] # 用于存放本局比赛中用到的所有内置bot

my_bot_team_name = '1' # 自己写的脚本控制的队伍名称
my_bot_team_player_name = []

for player in server.player_manager.get_players():
    if player.team_name == human_team_name:
        human_team_player_name.append(player.name)
    elif player.team_name == my_bot_team_name:
        my_bot_team_player_name.append(player.name)
    else:
        bot_agents.append(BotAgent(player.name, level=3))

fps_real = 0
t1 = time.time()
clock = pygame.time.Clock()
fps_set = server.state_tick_per_second

actioner = MySubmission(my_bot_team_name, my_bot_team_player_name)

for i in range(10000):

    obs = server.obs()
    actions = {bot_agent.name: bot_agent.step(obs[1][bot_agent.name]) for bot_agent in bot_agents}
    action1 = actioner.get_actions(obs)
    actions.update(action1)

    x, y = None, None
    action_type = -1
    # ================ control by keyboard ===============
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                x, y = 0, -1
                action_type = -1
            elif event.key == pygame.K_DOWN:
                x, y = 0, 1
                action_type = -1
            elif event.key == pygame.K_LEFT:
                x, y = -1, 0
                action_type = -1
            elif event.key == pygame.K_RIGHT:
                x, y = 1, 0
                action_type = -1
            elif event.key == pygame.K_q:  # Spores
                x, y = None, None
                action_type = 0
            elif event.key == pygame.K_w:  # Splite
                x, y = None, None
                action_type = 1
            elif event.key == pygame.K_e:  # Stop moving
                x, y = None, None
                action_type = 2
            elif event.key == pygame.K_r:  # Cheating, adding weight
                x, y = None, None
                action_type = -1
                server.player_manager.get_players()[0].get_balls()[0].set_size(144)
    action2 = {player_name: [x, y, action_type] for player_name in human_team_player_name}
    actions.update(action2)

    if server.last_time < server.match_time:
        server.step(actions)  # 用于保存录像
        if actions is not None and x is not None and y is not None:
            render.fill(server, direction=Vector2(x, y), fps=fps_real, last_time=server.last_time)
        else:
            render.fill(server, direction=None, fps=fps_real, last_time=server.last_time)
        render.show()  # 实时显示游戏画面
        if i % server.state_tick_per_second == 0:
            t2 = time.time()
            fps_real = server.state_tick_per_second / (t2 - t1)
            t1 = time.time()
    else:
        print('Game Over')
        break
    clock.tick(fps_set)
    if i%server.state_tick_per_second==0:
        print('{} {} {:.4f} leaderboard={}'.format(time.time(), i, server.last_time, obs[0]['leaderboard']))
server.step() # 用于保存录像

render.close()
server.close()